/// 简化的隧道连接管理器
/// Flutter只负责传入参数，所有网络协议逻辑由Go实现

import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:ffi/ffi.dart';
import '../models/tunnel_models.dart';
import '../native/simple_tunnel_bindings.dart';
import '../config/app_config.dart';

/// 简化的隧道管理器 - 仅作为Go实现的接口层
class SimpleTunnelManager {
  static SimpleTunnelManager? _instance;
  static SimpleTunnelManager get instance => _instance ??= SimpleTunnelManager._();
  
  SimpleTunnelManager._();
  
  bool _isConnected = false;
  String? _currentTunnelId;
  
  // 状态回调
  Function(String state, String message)? onStateChange;
  Function(double progress, double speed)? onProgress;
  Function(String error)? onError;
  
  /// 创建并连接隧道
  /// 所有网络逻辑由Go实现，Flutter只传入参数
  Future<bool> createAndConnect({
    required String tunnelId,
    required String tunnelServerHost,
    required int tunnelServerPort,
    required String targetHost,
    required int targetPort,
  }) async {
    try {
      debugPrint('🚀 创建隧道连接...');
      debugPrint('   隧道ID: $tunnelId');
      debugPrint('   隧道服务器: $tunnelServerHost:$tunnelServerPort');
      debugPrint('   目标服务: $targetHost:$targetPort');
      
      // 设置回调函数
      await _setupCallbacks();
      
      // 调用Go实现创建并连接隧道
      final tunnelIdPtr = tunnelId.toNativeUtf8();
      final tunnelServerHostPtr = tunnelServerHost.toNativeUtf8();
      final targetHostPtr = targetHost.toNativeUtf8();
      
      final createFunc = await SimpleTunnelBindings.createAndConnectTunnel;
      final result = createFunc(
        tunnelIdPtr,
        tunnelServerHostPtr,
        tunnelServerPort,
        targetHostPtr,
        targetPort,
      );
      
      // 释放内存
      malloc.free(tunnelIdPtr);
      malloc.free(tunnelServerHostPtr);
      malloc.free(targetHostPtr);
      
      if (result == 1) {
        _isConnected = true;
        _currentTunnelId = tunnelId;
        debugPrint('✅ Go隧道连接成功: $tunnelId');
        return true;
      } else {
        debugPrint('❌ Go隧道连接失败');
        onError?.call('Go隧道连接失败');
        return false;
      }
    } catch (e) {
      debugPrint('❌ 隧道连接异常: $e');
      onError?.call('连接异常: $e');
      return false;
    }
  }
  
  /// 断开隧道连接
  Future<bool> disconnect() async {
    try {
      debugPrint('🔌 [SimpleTunnelManager] 开始断开隧道: tunnelId=$_currentTunnelId, isConnected=$_isConnected');
      
      // 🔥🔥🔥 关键修复：无论Flutter端状态如何，都要调用Go层断开
      // 原因：Flutter端的_isConnected可能不准确，Go层的连接池可能还在运行
      // if (!_isConnected) return true; // ❌ 移除这个早期返回
      
      // 调用Go实现断开连接
      debugPrint('🔌 [SimpleTunnelManager] 调用Go FFI断开连接...');
      final disconnectFunc = await SimpleTunnelBindings.disconnectTunnel;
      final result = disconnectFunc();
      debugPrint('🔌 [SimpleTunnelManager] Go FFI返回结果: $result');
      
      if (result == 1) {
        _isConnected = false;
        _currentTunnelId = null;
        debugPrint('✅ [SimpleTunnelManager] Go隧道已断开');
        return true;
      } else {
        debugPrint('❌ [SimpleTunnelManager] Go隧道断开失败，返回值=$result');
        // 即使失败，也重置Flutter端状态
        _isConnected = false;
        _currentTunnelId = null;
        return false;
      }
    } catch (e, stackTrace) {
      debugPrint('❌ [SimpleTunnelManager] 断开连接异常: $e');
      debugPrint('   堆栈跟踪: $stackTrace');
      onError?.call('断开异常: $e');
      // 即使异常，也重置Flutter端状态
      _isConnected = false;
      _currentTunnelId = null;
      return false;
    }
  }
  
  /// 检查连接状态
  bool get isConnected => _isConnected;
  
  /// 获取当前隧道ID
  String? get currentTunnelId => _currentTunnelId;
  
  /// 获取连接统计信息
  Map<String, dynamic> get stats {
    return {
      'connected': _isConnected,
      'tunnelId': _currentTunnelId,
      'timestamp': DateTime.now().toIso8601String(),
    };
  }
  
  /// 设置日志级别
  void setLogLevel(int level) {
    debugPrint('📝 设置日志级别: $level');
    // TODO: 调用Go实现
    // GoTunnelManager.setLogLevel(level)
  }
  
  /// 获取版本信息
  String get version {
    // TODO: 调用Go实现
    // return GoTunnelManager.getVersion()
    return '1.0.0-simple';
  }
  
  /// 销毁管理器
  Future<void> dispose() async {
    if (_isConnected) {
      await disconnect();
    }
    
    try {
      final destroyFunc = await SimpleTunnelBindings.destroyManager;
      destroyFunc();
    } catch (e) {
      debugPrint('❌ 销毁Go管理器失败: $e');
    }
    
    _instance = null;
    debugPrint('🗑️ 简化隧道管理器已销毁');
  }
  
  /// 设置回调函数
  Future<void> _setupCallbacks() async {
    try {
      // 状态变化回调
      final stateChangeCallback = Pointer.fromFunction<StateChangeCallbackC>(_onStateChange);
      
      // 进度回调
      final progressCallback = Pointer.fromFunction<ProgressCallbackC>(_onProgress);
      
      // 错误回调
      final errorCallback = Pointer.fromFunction<ErrorCallbackC>(_onError);
      
      final setCallbacksFunc = await SimpleTunnelBindings.setCallbacks;
      setCallbacksFunc(stateChangeCallback, progressCallback, errorCallback);
      
      debugPrint('✅ Go回调函数已设置');
    } catch (e) {
      debugPrint('❌ 设置Go回调函数失败: $e');
    }
  }
  
  /// 静态回调函数 - 状态变化
  static void _onStateChange(Pointer<Utf8> state, Pointer<Utf8> message) {
    try {
      final stateStr = state.toDartString();
      final messageStr = message.toDartString();
      
      // 异步处理回调，避免阻塞UI线程
      Future.microtask(() {
        debugPrint('🔄 Go状态变化: $stateStr - $messageStr');
        
        if (instance.onStateChange != null) {
          instance.onStateChange!(stateStr, messageStr);
        }
      });
    } catch (e) {
      debugPrint('❌ 处理状态变化回调失败: $e');
    }
  }
  
  /// 静态回调函数 - 进度更新
  static void _onProgress(double progress, double speed) {
    try {
      // 异步处理回调，避免阻塞UI线程，并减少日志频率
      Future.microtask(() {
        // 只在重要进度点记录日志
        if (progress == 0.0 || progress >= 1.0 || (progress * 100) % 25 == 0) {
          debugPrint('📊 Go传输进度: ${(progress * 100).toStringAsFixed(1)}%');
        }
        
        if (instance.onProgress != null) {
          instance.onProgress!(progress, speed);
        }
      });
    } catch (e) {
      debugPrint('❌ 处理进度回调失败: $e');
    }
  }
  
  /// 静态回调函数 - 错误处理
  static void _onError(Pointer<Utf8> error) {
    try {
      final errorStr = error.toDartString();
      
      // 异步处理回调，避免阻塞UI线程
      Future.microtask(() {
        debugPrint('❌ Go错误: $errorStr');
        
        if (instance.onError != null) {
          instance.onError!(errorStr);
        }
      });
    } catch (e) {
      debugPrint('❌ 处理错误回调失败: $e');
    }
  }
}

/// 简化的隧道服务 - 替代复杂的AppService
class SimpleTunnelService {
  static final SimpleTunnelManager _manager = SimpleTunnelManager.instance;
  
  /// 创建隧道连接 - 简化接口
  static Future<TunnelConnectionResult> createTunnel({
    required String serverName,
    required String localHost,
    required String localPort,
    String? tunnelId, // 可选的隧道ID，如果提供则使用，否则生成新的
    Function(String state, String message)? onStateChange, // 状态变化回调
    Function(String error)? onError, // 错误回调
  }) async {
    try {
      debugPrint('🔧 创建隧道: $serverName ($localHost:$localPort)');
      
      // 1. 设置Go回调函数，确保状态变化能通知到Flutter
      setCallbacks(
        onStateChange: (state, message) {
          debugPrint('🔄 Go隧道状态变化: $state - $message');
          onStateChange?.call(state, message);
        },
        onError: (error) {
          debugPrint('❌ Go隧道错误: $error');
          onError?.call(error);
        },
      );
      
      // 2. 调用后端API创建隧道，获取服务器返回的隧道地址
      // 注意：这里需要通过依赖注入获取TunnelRepository，暂时使用legacy方式
      // TODO: 重构为使用Riverpod Provider
      
      // 使用传入的隧道ID或生成新的
      final actualTunnelId = tunnelId ?? 'tunnel-${DateTime.now().millisecondsSinceEpoch}';
      
      final appConfig = AppConfig.instance;
      final tunnelData = TunnelData(
        tunnelId: actualTunnelId,
        serverName: serverName,
        localHost: localHost,
        localPort: localPort,
        tunnelHost: appConfig.tcpTunnelHost, // 暂时使用配置文件中的IP
        tunnelPort: appConfig.tcpTunnelPort.toString(), // 暂时使用配置文件中的端口
        publicPort: '8080',
        publicAddress: 'http://$actualTunnelId.${appConfig.defaultDomain}',
        tunnelType: 'http',
      );
      
      // 3. 使用Go实现建立连接（异步连接，通过回调通知结果）
      debugPrint('🔄 开始Go隧道连接...');
      final requestAccepted = await _manager.createAndConnect(
        tunnelId: tunnelData.tunnelId,
        tunnelServerHost: tunnelData.tunnelHost,
        tunnelServerPort: int.parse(tunnelData.tunnelPort),
        targetHost: localHost,
        targetPort: int.parse(localPort),
      );
      
      debugPrint('🔄 Go连接请求结果: $requestAccepted');
      
      if (requestAccepted) {
        debugPrint('✅ Go隧道连接成功');
        // Go返回1表示连接请求已接受，认为连接成功
        // 实际的TCP连接状态通过回调监控，但不影响UI状态
        return TunnelConnectionResult.success(
          tunnelData: tunnelData,
          message: '隧道创建成功',
        );
      } else {
        debugPrint('❌ Go隧道连接失败');
        return TunnelConnectionResult.failure(
          error: 'Go隧道连接失败',
        );
      }
    } catch (e) {
      debugPrint('❌ 创建隧道失败: $e');
      return TunnelConnectionResult.failure(
        error: '创建失败: $e',
      );
    }
  }
  
  /// 断开隧道
  static Future<bool> disconnectTunnel(String tunnelId) async {
    debugPrint('🔌 断开隧道: $tunnelId');
    return await _manager.disconnect();
  }
  
  /// 检查隧道状态
  static bool isTunnelConnected(String tunnelId) {
    return _manager.isConnected && _manager.currentTunnelId == tunnelId;
  }
  
  /// 获取所有活跃连接
  static List<String> getActiveTunnels() {
    if (_manager.isConnected && _manager.currentTunnelId != null) {
      return [_manager.currentTunnelId!];
    }
    return [];
  }
  
  /// 设置回调函数
  static void setCallbacks({
    Function(String state, String message)? onStateChange,
    Function(double progress, double speed)? onProgress,
    Function(String error)? onError,
  }) {
    _manager.onStateChange = onStateChange;
    _manager.onProgress = onProgress;
    _manager.onError = onError;
  }
}

/// 隧道连接结果
class TunnelConnectionResult {
  final bool success;
  final TunnelData? tunnelData;
  final String? error;
  final String? message;
  
  TunnelConnectionResult._({
    required this.success,
    this.tunnelData,
    this.error,
    this.message,
  });
  
  factory TunnelConnectionResult.success({
    required TunnelData tunnelData,
    String? message,
  }) {
    return TunnelConnectionResult._(
      success: true,
      tunnelData: tunnelData,
      message: message,
    );
  }
  
  factory TunnelConnectionResult.failure({
    required String error,
  }) {
    return TunnelConnectionResult._(
      success: false,
      error: error,
    );
  }
}
